package sg.edu.nus.iss.cats.dataaccess.hibernate;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import sg.edu.nus.iss.cats.exception.HibernateAccessLayerException;
import sg.edu.nus.iss.cats.model.Course;

public abstract class AbstractDao {
	private Session session;

	private Transaction tx;

	public AbstractDao() {
		HibernateFactory.buildIfNeeded();
	}

	protected void saveOrUpdate(Object obj) {
		try {
			startOperation();
			session.saveOrUpdate(obj);
			
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
		}
	}

	protected void delete(Object obj) {
		try {
			startOperation();
			session.delete(obj);
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
		}
	}

	protected Object find(Class clazz, String id) {
		Object obj = null;
		try {
			startOperation();
			obj = session.get(clazz, id);
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
			
		}
		return obj;
	}
	protected Object find(Class clazz, Integer id) {
		Object obj = null;
		try {
			startOperation();
			obj = session.get(clazz, id);
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
			
		}
		return obj;
	}
	protected List findAll(Class clazz) {
		List objects = null;
		try {
			startOperation();
			Query query = session.createQuery("from " + clazz.getName());
			objects = query.list();
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
		}
		return objects;
	}

	protected List findByCategory(Class clazz, String cat, String param) {
		List objects = null;
		try {
			startOperation();
			String hql = "from " + clazz.getName() + " c where c." + cat.trim()
					+ "= '" + param.trim() + "'";
			Query query = session.createQuery(hql);
			objects = query.list();
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
		}
		return objects;
	}

	protected void handleException(HibernateException e)
			throws HibernateAccessLayerException {
		HibernateFactory.rollback(tx);
		throw new HibernateAccessLayerException(e);
	}

	protected void startOperation() throws HibernateException {
		session = HibernateFactory.openSession();
		tx = session.beginTransaction();
	}

	protected List findByQuery(String hql) {
		List objects = null;
		try {
			startOperation();
			objects = session.createSQLQuery(hql).addEntity("c", Course.class).list();
			tx.commit();
		} catch (HibernateException e) {
			handleException(e);
		} finally {
			HibernateFactory.close(session);
		}
		return objects;
	}
}
